package cn.wolfcode.p2p.bussness.service.impl;

import cn.wolfcode.p2p.base.domain.Account;
import cn.wolfcode.p2p.base.service.IAccountService;
import cn.wolfcode.p2p.base.util.Constants;
import cn.wolfcode.p2p.bussness.domain.BidRequest;
import cn.wolfcode.p2p.bussness.domain.PaymentSchedule;
import cn.wolfcode.p2p.bussness.domain.PaymentScheduleDetail;
import cn.wolfcode.p2p.bussness.domain.SystemAccount;
import cn.wolfcode.p2p.bussness.mapper.PaymentScheduleMapper;
import cn.wolfcode.p2p.bussness.query.PaymentScheduleQueryObject;
import cn.wolfcode.p2p.bussness.service.*;
import cn.wolfcode.p2p.bussness.util.CalculatetUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class PaymentScheduleServiceImpl implements IPaymentScheduleService {
    @Autowired
    private PaymentScheduleMapper paymentScheduleMapper;
    @Autowired
    private IAccountService accountService;
    @Autowired
    private IPaymentScheduleDetailService paymentScheduleDetailService;
    @Autowired
    private IAccountFlowService accountFlowService;
    @Autowired
    private ISystemAccountService systemAccountService;
    @Autowired
    private ISystemAccountFlowService systemAccountFlowService;
    @Autowired
    private IBidRequestService bidRequestService;
    @Autowired
    private IBidService bidService;

    @Override
    public int save(PaymentSchedule paymentSchedule) {
        return paymentScheduleMapper.insert(paymentSchedule);
    }

    @Override
    public int update(PaymentSchedule paymentSchedule) {
        return paymentScheduleMapper.updateByPrimaryKey(paymentSchedule);
    }

    @Override
    public PaymentSchedule get(Long id) {
        return paymentScheduleMapper.selectByPrimaryKey(id);
    }

    @Override
    public PageInfo queryPage(PaymentScheduleQueryObject qo) {
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());
        List result = paymentScheduleMapper.queryList(qo);
        return new PageInfo(result);
    }

    //立即还款
    @Override
    public void returnMoney(Long id) {
        //根据id查询还款对象,判断还款对象是否处于征程待还
        PaymentSchedule paymentSchedule = paymentScheduleMapper.selectByPrimaryKey(id);
        if (paymentSchedule != null && paymentSchedule.getState() == Constants.PAYMENT_STATE_NORMAL) {
            Account aurrount = accountService.getCurrent();
            if (aurrount.getId().equals(paymentSchedule.getBorrowUser().getId()) && //判断当前登录的用户是否是借款人
                    //        可用金额                                      本期还款金额
                    aurrount.getUsableAmount().compareTo(paymentSchedule.getTotalAmount()) >= 0) {//当前登录用户的可用金额?=改期的还款金额
                //需要对还款对象和还款明细对象属性的设置
                // 设置还款时间
                paymentSchedule.setPayDate(new Date());
                // 设置还款状态
                paymentSchedule.setState(Constants.PAYMENT_STATE_DONE);//已还
                this.update(paymentSchedule);
                //对还款明细对象统一更新还款时间
                paymentScheduleDetailService.updatePayDate(paymentSchedule.getId(), paymentSchedule.getPayDate());
                //对于借款人
                //可用金额减少,待还本息减少,剩余授信额度增加
                aurrount.setUsableAmount(aurrount.getUnReturnAmount().subtract(paymentSchedule.getTotalAmount()));
                aurrount.setUnReturnAmount(aurrount.getUnReturnAmount().subtract(paymentSchedule.getTotalAmount()));
                //剩余授信额度 = 远胜于授信额度 + 改期还款本金
                aurrount.setRemainBorrowLimit(aurrount.getRemainBorrowLimit().add(paymentSchedule.getPrincipal()));
                accountService.updateByPrimaryKey(aurrount);
                //生成还款成功的流水
                accountFlowService.createRechargeMarageFlow(aurrount,paymentSchedule.getTotalAmount());
                //对于投资人的属性设置
                Map<Long,Account> accountMap = new HashMap<Long, Account>();
                Account bidUserAooun;
                Long bidUserId;
                SystemAccount systemAccount = systemAccountService.getCurrent();
                for (PaymentScheduleDetail psd : paymentSchedule.getDetails()) {
                    bidUserId = psd.getInvestorId();
                    bidUserAooun = accountMap.get(bidUserId);
                    if (bidUserAooun == null) {
                        bidUserAooun = accountService.get(bidUserId);
                        accountMap.put(bidUserId,bidUserAooun);
                    }
                    //投资人的可用金额增加
                    bidUserAooun.setUsableAmount(bidUserAooun.getUsableAmount().add(psd.getTotalAmount()));
                    //待收本金减少
                    bidUserAooun.setUnReceivePrincipal(bidUserAooun.getUnReceivePrincipal().subtract(psd.getPrincipal()));
                    //代收利息减少
                    bidUserAooun.setUnReceiveInterest(bidUserAooun.getUnReceiveInterest().subtract(psd.getInterest()));
                    //生成退款成功的流水
                    accountFlowService.creagainReturnMoneyFlow(bidUserAooun,psd.getTotalAmount());
                    //支付平台的利息管理给,生成流水
                    BigDecimal interestManagerCharge = CalculatetUtil.calInterestManagerCharge(psd.getInterest());
                    bidUserAooun.setUsableAmount(bidUserAooun.getUsableAmount().subtract(interestManagerCharge));
                    systemAccountFlowService.createPayInterretManagerChargeFlow(systemAccount,interestManagerCharge);
                }
                //对普通用户同意修改
                for (Account accountTemp : accountMap.values()) {
                    accountService.updateByPrimaryKey(accountTemp);
                }
                systemAccountService.update(systemAccount);
                //对系统账户同意修改,如何判断还款已经还请
                List<PaymentSchedule> paymentSchedules = this.paymentScheduleMapper.queryPaymentScheduleByBidRequestId(paymentSchedule.getBidRequestId());
                //根据借款的id查询该借款下的所有借款对象,判断状态是否都等于已还
                for (PaymentSchedule ps : paymentSchedules) {
                    if (ps.getState() != Constants.PAYMENT_STATE_DONE) {
                        //如果进入到这里,说明还存在还款对象,就是没有还请
                        return;
                    }
                }
                //如果已经还请之后,对于借款对象和投标对象需要设置的属性
                BidRequest bidRequest = bidRequestService.get(paymentSchedule.getBidRequestId());
                bidRequest.setBidRequestState(Constants.BIDREQUEST_STATE_COMPLETE_PAY_BACK);
                bidRequestService.update(bidRequest);
                //借款对象和投标对象需要设置状态为已完成
                bidService.updateState(bidRequest.getId(),Constants.BIDREQUEST_STATE_COMPLETE_PAY_BACK);
            }
        }
    }
}
